package emailserving.domain;

import emailserving.common.Utils;
import org.apache.commons.lang.Validate;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "es_jobs")
public class Job extends AbstractModel {

    private static final Find<Long, Job> find = new Find<Long, Job>() {
    };

    public Job(String name) {
        this.name = name;
    }

    @Column(name = "name", length = 40, nullable = false, unique = true)
    private String name;

    @Column(name = "sender_email", nullable = false, unique = true)
    private String senderEmail;


    @Column(name = "start_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date startTime;

    @Column(name = "finish_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date finishTime;


    public boolean haventStart() {
        return startTime == null;
    }

    public int hadBeenSentEmailCount() {
        Validate.notNull(getId());
        return Contact.hadBeenSentEmailCount(getId());
    }

    public int contactsTotalCount() {
        Validate.notNull(getId());
        return Contact.contactsTotalCount(getId());
    }

    public double percentComplete() {
        long total = contactsTotalCount();
        if (total <= 0) {
            return 0;
        } else {
            return Double.valueOf("" + hadBeenSentEmailCount()) / contactsTotalCount() * 100;
        }
    }

    public long getUsedMinute() {
        if (getFinishTime() != null && getStartTime() != null) {
            return Utils.diffMinutesBetween2Date(getStartTime(), getFinishTime());
        } else {
            return 0;
        }
    }

    public static void main(String[] args) {

        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        System.out.println((new Date(2014, 1, 2).getTime() - new Date(2014, 1, 1).getTime()) / nd / nh / nm);

    }

    public static List<Job> findNameLike(String name, int pageIndex, int pageSize) {
        return find.where().where()
                .like("name", "%" + name + "%").findPagedList(pageIndex, pageSize).getList();
    }

    public static void refreshAllJobsExecutingStatus() {
        Timestamp timestamp = new Timestamp(new Date().getTime());
        String sql = String.format("UPDATE es_jobs SET finish_time ='%s'  WHERE id in (select job_id from es_contacts where sent_time is not null group by job_id)", timestamp);
        db().createSqlUpdate(sql).execute();
    }


    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getFinishTime() {
        return finishTime;
    }

    public void setFinishTime(Date finishTime) {
        this.finishTime = finishTime;
    }

    public String getSenderEmail() {
        return senderEmail;
    }

    public void setSenderEmail(String senderEmail) {
        this.senderEmail = senderEmail;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Job job = (Job) o;

        if (name != null ? !name.equals(job.name) : job.name != null) return false;
        if (startTime != null ? !startTime.equals(job.startTime) : job.startTime != null) return false;
        return !(finishTime != null ? !finishTime.equals(job.finishTime) : job.finishTime != null);

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (startTime != null ? startTime.hashCode() : 0);
        result = 31 * result + (finishTime != null ? finishTime.hashCode() : 0);
        return result;
    }


    public static Job findById(long jobId) {
        return find.where().eq("id", jobId).findUnique();
    }


    public static void updateJobStartTime(long jobId) {
        Job job = findById(jobId);
        if (job != null && job.haventStart()) {
            job.setStartTime(new Date());
            db().update(job);
        }
    }
}
